// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Circle_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Circle_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Circle_2_doc[]={
"An object of type Circle_2 is a circle in the two-dimensional Euclidean plane. \n\
The circle is oriented, i.e. its boundary has clockwise or counterclockwise orientation . \n\
The boundary splits E x E into a positive and a negative side, \n\
where the positive side is to the left of the boundary. \n\
The boundary also splits E x E into a bounded and an unbounded side. \n\
Note that the circle can be degenerated, i.e. the squared radius may be zero.\n\
For more details see a C++ doc:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Circle_2.html",
"\
c = Circle_2( Point_2 center,squared_radius,Orientation ori = COUNTERCLOCKWISE)\
introduces a variable c of type Circle_2. \nIt is initialized to the circle with center center, squared radius squared_radius and orientation ori.\n\
Precondition: ori COLLINEAR, and further, squared_radius 0.\n\n\
c = Circle_2( Point_2 p,Point_2 q,Point_2 r);\n\
introduces a variable c of type Circle_2. \nIt is initialized to the unique circle which passes through the points p, q and r. \nThe orientation of the circle is the orientation of the point triple p, q, r.\n\
Precondition: p, q, and r are not collinear.\n\n\
c = Circle_2( Point_2 p,Point_2 q,Orientation ori = COUNTERCLOCKWISE)\n\n\
introduces a variable c of type Circle_2. It is initialized to the circle with diameter pq and orientation ori.\n\
Precondition: ori COLLINEAR.\n\
c = Circle_2( Point_2 center,Orientation ori = COUNTERCLOCKWISE)\n\
introduces a variable c of type Circle_2. \nIt is initialized to the circle with center center, squared radius zero and orientation ori.\n\
Precondition: ori COLLINEAR.\n\
Postcondition: c.is_degenerate() = true.",

"c.center(self) ->Point_2\nreturns the center of c.",

"c.squared_radius(self) ->double\nreturns the squared radius of c.",

"c.orientation(self) -> Orientation\nreturns the orientation of c.",

"c.bounded_side(self, Point_2 p) -> Bounded_side\nreturns ON_BOUNDED_SIDE, ON_BOUNDARY, \n\
or ON_UNBOUNDED_SIDE  iff p lies properly inside, on the boundary, or properly outside of c, resp.",

"c.oriented_side(self ,Point_2 p) ->Oriented_side\nreturns either the constant ON_ORIENTED_BOUNDARY, ON_POSITIVE_SIDE, \n\
or ON_NEGATIVE_SIDE, iff p lies on the boundary, properly on \n\
the positive side, or properly on the negative side of c, resp.",

"c.has_on_boundary(self , Point_2 p) -> bool",

"c.has_on_bounded_side(self , Point_2 p) -> bool",

"c.has_on_unbounded_side(self , Point_2 p) -> bool",

"c.has_on_negative_side(self , Point_2 p) -> bool",

"c.has_on_positive_side(self , Point_2 p) -> bool",

"c.is_degenerate(self) -> bool\nreturns true, iff c is degenerate, i.e. if c has squared radius zero.",

"c.opposite(self) -> Circle_2\nreturns the circle with the same center and squared radius as c but with opposite orientation .",

"c.bbox(self) -> Bbox_2\nreturns a bounding box containing c."
};

template<class Circle_2>
boost::python::str py_repr_Circle_2(const Circle_2& c )
{
	using namespace boost::python;
	return str("Circle_2("+ str(c.center()) +","+ str(c.squared_radius())+","+ str(c.orientation()) +")" );
}

template<class kernel>
void Py_Circle_2()
{
	using namespace boost::python;

	typedef typename kernel::Point_2 					Point_2;
	typedef typename kernel::Circle_2 				      	Circle_2;
	typedef typename kernel::Aff_transformation_2 				Aff_transformation_2;
	typedef typename kernel::FT 						FT;
	typedef typename kernel::RT						RT;

        class_< Circle_2  >("Circle_2", Circle_2_doc[0], init<>())
        .def(init< const Circle_2& >(Circle_2_doc[1]))
        .def(init< const Point_2&, const FT&, const CGAL::Orientation& >())
        .def(init< const Point_2&, const FT& >())
        .def(init< const Point_2&, const double&, const CGAL::Orientation& >())
        .def(init< const Point_2&, const double& >())
        .def(init< const Point_2&, const Point_2&, const Point_2& >())
        .def(init< const Point_2&, const Point_2&, const CGAL::Orientation& >())
        .def(init< const Point_2&, const Point_2& >())
        .def(init< const Point_2&, const CGAL::Orientation& >())
        .def(init< const Point_2& >())
#if CGAL_VERSION_NR < 1030301000
        .def("center", &Circle_2::center, by_cref(), Circle_2_doc[2])
        .def("squared_radius", &Circle_2::squared_radius, by_cref(), Circle_2_doc[3])
#else
        .def("center", &Circle_2::center, typename Value_or_cref<typename kernel::Construct_center_2, Circle_2 > ::type(), Circle_2_doc[2])
        .def("squared_radius", &Circle_2::squared_radius, typename Value_or_cref<typename kernel::Compute_squared_radius_2, Circle_2 > ::type(), Circle_2_doc[3])
#endif
        .def("orientation", &Circle_2::orientation, Circle_2_doc[4])
        .def("bounded_side", &Circle_2::bounded_side, Circle_2_doc[5])
        .def("oriented_side", &Circle_2::oriented_side, Circle_2_doc[6])
        .def("has_on_boundary", &Circle_2::has_on_boundary, Circle_2_doc[7])
        .def("has_on_bounded_side", &Circle_2::has_on_bounded_side, Circle_2_doc[8])
        .def("has_on_unbounded_side", &Circle_2::has_on_unbounded_side, Circle_2_doc[10])
        .def("has_on_negative_side", &Circle_2::has_on_negative_side, Circle_2_doc[11])
        .def("has_on_positive_side", &Circle_2::has_on_positive_side, Circle_2_doc[12])
        .def("is_degenerate", &Circle_2::is_degenerate, Circle_2_doc[13])
        .def("opposite", &Circle_2::opposite, Circle_2_doc[14])
        .def("bbox", &Circle_2::bbox, Circle_2_doc[15])
	.def("__repr__", &py_repr_Circle_2<Circle_2>)
        .def( self == self )
        .def( self != self )
    ;
}


void export_Circle_2()
{
	Py_Circle_2<K>();
}
